import typing
import threading
import time
from PySide6.QtCore import QMutex, QObject, QThread, Signal, qRegisterResourceData
import PySide6.QtCore
from typing import Callable, Optional


class ThreadReadBuffer(QThread):
    def __init__(
        self, 
        func: typing.Callable,
        parent: Optional[PySide6.QtCore.QObject] = None) -> None:
        super().__init__(parent=parent)
        self._func = func
    
    def run(self) -> None:
        self._func()

class ActiveDataBuffer(QObject):
    '''
    description:
        一个数据缓冲类，可以往里面放数据
        使能后会开启一个线程，定时的把数据取出来
        传入设定的函数
    '''
    signalSendBuffer = Signal(list)
    # def __init__(self) -> None:
    #     super().__init__()
    def __init__(
        self, 
        parent: Optional[PySide6.QtCore.QObject] = None) -> None:
        super().__init__(parent=parent)
    
    def ADBBufferEnalbe(
        self,
        func: typing.Callable[[typing.List[typing.Any]], None],
        period: 'float' = 0.05,
        max_count: 'int' = 10000) -> 'bool':
        '''
        fucntion:
            使能ADB数据Buffer:
            - 创建一个List, 和一个递归锁对象
            - 开启一个线程，循环的向该List中取数据，取到东西后会调用设定的函数
        args:
            func callable 循环触发的函数
            period float 多久事件会获取一次数据
            max_count int buffer中最多放置多少数据
        return:
            bool 是否 Enable 成功

        此函数创建的类内常量：
            - _isEnable bool 指示是否开启
            - _callback callable 本对象在更新数据后传入的函数
            - _buffer list 存放数据的buffer
            - _task Thread 循环读取 buffer 数据的线程
            - _period float 循环读取 buffer 数据的时间
            - _maxCount int buffer的最大数量
            - _lock RLock 访问Buffer的锁
        '''
        # TODO 赵树成 实现功能
        if (not hasattr(self, '_isEnable')):
            self._isEnable = False
        if (self._isEnable):
            return False
        self._isEnable = True
        self._callback = func
        self._period = period
        self._maxCount = max_count
        self._buffer = list()
        self.signalSendBuffer.connect(func)
        self._task = ThreadReadBuffer(self._ADBSendData)
        self._task.start()
        return True

    def ADBBufferDisable(self) -> 'bool':
        '''
        function:
            禁能 ADB Buffer 功能
        '''
        self._isEnable = False
        return True

    def ADBAdd(
        self,
        data: typing.Any) -> 'bool':
        '''
        function:
            向本 ADBBuffer 添加一个数据
        '''
        if (not hasattr(self, '_isEnable')):
            return False
        if (not self._isEnable):
            return False
        if (not len(self._buffer) < self._maxCount):
            return False
        # self._lock.lock()
        self._buffer.append(data)
        # self._lock.unlock()
        return True

    def ADBPopAll(self) -> typing.List[typing.Any]:
        '''
        function:
            获取当前所有的数据并清空Buffer
        '''
        # l_ = list()
        if (not hasattr(self, '_isEnable')):
            return list()
        if (not self._isEnable):
            return list()
        if (len(self._buffer) > 0):
            # self._lock.acquire(True)
            l_ = self._buffer
            self._buffer = list()
            # self._lock.release()
            return l_
        return list()

    def ADBSetPeriod(self, period: 'float') -> 'bool':
        '''
        function:
            设置本对象的清空Buffer的时间
        '''
        self._period = period
        return True

    def _ADBSendData(self) -> None:
        '''
        function:
            本对象的设置函数的主任务函数
            循环的向本对象在启动的时候设置的回调函数中
            传入数据
        '''
        if (not hasattr(self, '_isEnable')):
            return
        while (True):
            if (self._isEnable):
                l_ = self.ADBPopAll()
                if (len(l_) > 0):
                    self.signalSendBuffer.emit(l_)
                time.sleep(self._period)
            else:
                break
        return